package com.ideaaedi.shardingdynamictable.mybatisPlus;

import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.generator.FastAutoGenerator;
import com.baomidou.mybatisplus.generator.config.ConstVal;
import com.baomidou.mybatisplus.generator.config.DataSourceConfig;
import com.baomidou.mybatisplus.generator.config.TemplateConfig;
import com.baomidou.mybatisplus.generator.config.converts.MySqlTypeConvert;
import com.baomidou.mybatisplus.generator.config.rules.DbColumnType;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;
import com.baomidou.mybatisplus.generator.fill.Property;
import com.ideaaedi.commonds.io.IOUtil;
import com.ideaaedi.commonds.path.PathUtil;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.test.context.SpringBootTest;

import java.io.File;

/**
 * mybatis-plus代码生成 &emsp;
 * <a href="https://baomidou.com/pages/779a6e/#%E4%BD%BF%E7%94%A8">代码生成官网</a>
 * &emsp;
 * <a href="https://baomidou.com/pages/981406/#%E5%9F%BA%E7%A1%80%E9%85%8D%E7%BD%AE">配置说明官网</a>
 *
 * @author JustryDeng
 * @since 2022/6/28 9:26
 */
@SpringBootTest
public class MybatisPlusGeneratorHelper {
    
    @Value("${spring.datasource.hikari.jdbc-url}")
    private String url;
    
    @Value("${spring.datasource.hikari.username}")
    private String username;
    
    @Value("${spring.datasource.hikari.password}")
    private String password;
    
    @Test
    void generate() {
        String outputRootDir = PathUtil.getProjectRootDir(MybatisPlusGeneratorHelper.class)
                .replace("/target/test-classes/", "/src/test/java/");
        String packagePath = MybatisPlusGeneratorHelper.class.getPackage().getName() + ".generator";
        // 先清空./generator/目录
        IOUtil.delete(new File(outputRootDir + packagePath.replace(".", "/")));
        
        DataSourceConfig.Builder dsc = new DataSourceConfig.Builder(url, username, password);
        dsc.typeConvert((globalConfig, fieldType) -> {
            String columeType = fieldType.toLowerCase();
            if (columeType.contains("tinyint")) {
                return DbColumnType.INTEGER;
            }
            // 其它字段采用默认转换
            return new MySqlTypeConvert().processTypeConvert(globalConfig, fieldType);
        });
        // basic settings
        final FastAutoGenerator fastAutoGenerator = FastAutoGenerator.create(
                dsc
        
        )
                .globalConfig(builder -> builder
                        // 设置作者
                        .author("mybatis-plus generator")
                        .commentDate("yyyy-MM-dd HH:mm:ss")
                        // 指定输出目录
                        .outputDir(outputRootDir)
                )
                // 包配置
                .packageConfig(builder -> builder
                        // 指定生成的类的所属包
                        .parent(packagePath)
                        .entity("entity.po")
                        .service("service")
                        .serviceImpl("service.impl")
                        .mapper("mapper")
                        .xml("mapper.xml")
                        .controller("controller")
                        .other("other"))
                // 策略配置
                .strategyConfig(builder -> builder
                        // => 表配置
                        // 设置需要生成代码的表名（不设置则全库生成）
                        .addInclude(
                                "trans_record"
                        )
                        // 设置过滤表前缀
                        // .addTablePrefix("tmp_")
                        // 设置过滤表后缀
                        // .addTableSuffix("_tmp")
                        
                        // => entity配置
                        .entityBuilder()
                        .convertFileName((entityName) -> entityName + "PO")
                        /// 给po设置公共父类
                        ///.superClass(PoSupperEntity.class)
                        /// 设置生成的PO里面的对应字段有填充标识或者逻辑删除标识
                        /// // 逻辑删除字段名
                        .logicDeletePropertyName("del")
                        // 自动填充
                        .addTableFills(new Property("createdBy", FieldFill.INSERT))
                        .addTableFills(new Property("createdAt", FieldFill.INSERT))
                        .addTableFills(new Property("updatedBy", FieldFill.UPDATE))
                        .addTableFills(new Property("updatedAt", FieldFill.UPDATE))
                        // 启用TableField等相关注解
                        .enableTableFieldAnnotation()
                        .enableLombok()
                        
                        // => controller配置
                        .controllerBuilder()
                        .enableRestStyle()
                        .convertFileName((entityName) -> entityName + "Controller")
                        // .superClass(BaseController.class)
                        
                        // => service配置
                        .serviceBuilder()
                        .convertServiceFileName((entityName) -> entityName + "Service")
                        .convertServiceImplFileName((entityName) -> entityName + "ServiceImpl")
                        
                        // => mapper配置
                        .mapperBuilder()
                        .enableMapperAnnotation()
                        .convertMapperFileName((entityName) -> entityName + "Mapper")
                        .convertXmlFileName((entityName) -> entityName + "Mapper"))
                .templateEngine(new FreemarkerTemplateEngine());
        
        // entity、service、serviceImpl、controller、mapper、xml，使用指定模板生成
        fastAutoGenerator.templateConfig((TemplateConfig.Builder builder) -> {
            // 使用mybatis-plus-generator包下的默认模板
            builder
                    .entity(ConstVal.TEMPLATE_ENTITY_JAVA)
                    .mapper(ConstVal.TEMPLATE_MAPPER)
                    .xml(ConstVal.TEMPLATE_XML)
                    .service(ConstVal.TEMPLATE_SERVICE)
                    .serviceImpl(ConstVal.TEMPLATE_SERVICE_IMPL)
                    .controller(ConstVal.TEMPLATE_CONTROLLER)
            ;
        });
        
        fastAutoGenerator.execute();
    }
}
